package devin.chat.view;

import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 用于管理所有的 Stage
 *
 * 参考 http://blog.csdn.net/nthack5730/article/details/51901593
 *
 * @author devin
 */
public class StageManager {
    /** 日志 */
    private static final Logger LOGGER = LoggerFactory.getLogger(StageManager.class);

    /** 单例 */
    private static final StageManager manager = new StageManager();

    /** 用于存放所有的 stage */
    private Map<String, Stage> stages = new HashMap<>();

    /** 应用的名称 */
    private String appName;

    /** 图标路径 */
    private String iconPath;

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public String getIconPath() {
        return iconPath;
    }

    public void setIconPath(String iconPath) {
        this.iconPath = iconPath;
    }

    private StageManager() {
    }

    public static StageManager getInstance() {
        return manager;
    }

    /**
     * 添加 stage 进行管理
     * @param name stage 名称
     * @param stage stage 对象
     */
    public void addStage(String name, Stage stage) {
        LOGGER.info("add stage [{}]", name);
        stages.put(name, stage);
    }

    /**
     * 根据 stage 的名称返回 stage 对象
     * @param name stage 名称
     * @return stage 对象
     */
    public Stage getStage(String name) {
        return stages.get(name);
    }

    /**
     * 删除 stage
     * @param name stage 的名称
     * @return 被删除的 stage 对象
     */
    public Stage removeStage(String name) {
        Stage stage = stages.get(name);
        if (stage == null) {
            LOGGER.warn("invalid stage [{}]", name);
            return null;
        }

        // 关闭 stage
        if (stage.isShowing()) {
            LOGGER.warn("stage [{}] is showing", name);
            stage.close();
        }

        stages.remove(name);
        LOGGER.info("remove stage [{}]", name);
        return stage;
    }

    /**
     * 打开 stage
     * @param name 要打开的 stage 名称
     */
    public void showStage(String name) {
        Stage stage = stages.get(name);

        if (stage == null) {
            LOGGER.error("can not open, the stage [{}] not exist", name);
            return;
        }

        if (stage.isShowing()) {
            LOGGER.warn("stage [{}] is showing", name);
            return;
        }

        stage.show();
    }

    /**
     * 关闭 stage
     * @param name 要关闭的 stage 名称
     */
    public void closeStage(String name) {
        Stage stage = stages.get(name);

        if (stage == null) {
            LOGGER.error("stage [{}] not exist", name);
            return;
        }

        if (!stage.isShowing()) {
            LOGGER.warn("stage [{}] has been already closed", name);
            return;
        }

        stage.close();
    }

    /**
     * 加载 FXML 创建并管理 stage
     * @param clazz 对应 FXML 的 controller
     * @param resource FXML 文件的路径
     * @return 创建的 stage
     */
    public Stage loadStage(Class clazz, String resource) {
        return loadStage(clazz.getName(), resource, null, null);
    }

    /**
     * 加载 FXML 创建并管理 stage
     * @param name stage 名称
     * @param resource FXML 文件的路径
     * @return 创建的 stage
     */
    public Stage loadStage(String name, String resource) {
        return loadStage(name, resource, null, null);
    }

    /**
     * 加载 FXML 创建并管理 stage
     * @param name stage 名称
     * @param resource FXML 文件的路径
     * @param styles stage 的样式
     * @return 创建的 stage
     */
    public Stage loadStage(String name, String resource, String subtitle, StageStyle[] styles) {
        try {
            // 加载 FXML 资源
            FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
            Pane pane = loader.load();

            // 注入 stageManage 到 controller
            BaseController controller = loader.getController();
            controller.setManager(this);

            // 创建 stage
            Scene scene = new Scene(pane);
            Stage stage = new Stage();
            stage.setScene(scene);

            // 设置标题和图标
            StringBuilder titleBuilder = new StringBuilder();
            if (this.appName != null) {
                titleBuilder.append(this.appName);
            }
            if (subtitle != null) {
                titleBuilder.append(" - ").append(subtitle);
            }
            stage.setTitle(titleBuilder.toString());

            if (this.iconPath != null) {
                stage.getIcons().add(new Image(this.iconPath));
            }

            // 应用样式主题
            if (styles != null) {
                for (StageStyle style : styles) {
                    stage.initStyle(style);
                }
            }

            // 将 stage 交由 manger 统一管理
            this.addStage(name, stage);

            return stage;
        } catch (IOException e) {
            LOGGER.error("{} load error", resource, e);
            return null;
        }
    }
}
